﻿/*=====================================================================
  
    File:      TabularDatabase.Partition.cs

    Summary:   This is the class that implements all related functionality 
               around Partitions in a tabular model, for all TabularDatabase 
               commandlets.
 
               Tabular Database Cmdlets (TabularDatabaseCmdlets) is sample code 
               to show and explain how to use the AMO to Tabular (AMO2Tabular)
               library to build a PowerShell library of cmdlets to manage 
               Tabular model objects. 
               The sample can be seen as a sample library of cmdlets
               with the necessary code to execute each particular 
               action or operation over a logical tabular object. 

    Authors:   JuanPablo Jofre (jpjofre@microsoft.com)
    Date:	   04-Apr-2012
  
    Change history:

    @TODO: 
  
-----------------------------------------------------------------------
  
    This file is part of the Microsoft SQL Server Code Samples.
    Copyright (C) Microsoft Corporation.  All rights reserved.
  
  This source code is intended only as a supplement to Microsoft
  Development Tools and/or on-line documentation.  
  
  THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF 
  ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  PARTICULAR PURPOSE.
  
======================================================================*/


using System;
using System.Globalization;
using System.Management.Automation;     //  Windows PowerShell assembly.
using MicrosoftSql2012Samples.Amo2Tabular;
using MicrosoftSql2012Samples.TabularDatabaseCmdlet.Properties;
using AMO = Microsoft.AnalysisServices;

namespace MicrosoftSql2012Samples.TabularDatabaseCmdlet
{
    [Cmdlet(VerbsCommon.Add, "PartitionToTabularTable")]
    public class AddPartitionToTabularTable : TabularDatabaseBase
    {
        //  Declare mandatory parameters

        [Parameter(Mandatory = true, Position = 2)]
        [ValidateNotNullOrEmpty]
        public string tableName { get; set; }

        [Parameter(Mandatory = true, Position = 3)]
        [ValidateNotNullOrEmpty]
        public string partitionName { get; set; }

        [Parameter(Mandatory = true, Position = 4)]
        [ValidateNotNullOrEmpty]
        public string selectStatement { get; set; }


        // Declare optional parameters for the Add-PartitionToTabularTable cmdlet.
        [Parameter]
        public string process { get; set; }
        
        [Parameter]
        public string alternateConnectionName { get; set; }

        // Overide the ProcessRecord method to add a Partition
        // using the supplied server name and database name 
        protected override void ProcessRecord()
        {
            //  -   process string must be a valid AMO process type or empty/null
            AMO.ProcessType? processType = null;
            if (!process.IsNullOrEmptyOrWhitespace())
            {
                processType = TabularDatabaseHelperFunctions.TryParseProcessType(process);
                if (processType == null)
                    ThrowTerminatingError(new ErrorRecord(new ArgumentException(string.Format(CultureInfo.InvariantCulture, Resources.InvalidProcessValueArgumentException, process)), string.Empty, ErrorCategory.InvalidArgument, null));
            }

            using (AMO.Server server = new AMO.Server())
            {
                try
                {
                    server.Connect(serverName);
                    using (AMO.Database database = server.Databases.GetByName(databaseName))
                    {
                        AMO2Tabular.PartitionAdd(database, tableName, partitionName, selectStatement, true, processType, alternateConnectionName);
                        WriteVerbose(string.Format(CultureInfo.InvariantCulture, Resources.AddPartitionToTabularTableWriteReport, partitionName, tableName));
                    }
                }
                catch (Exception ex)
                {
                    ThrowTerminatingError(new ErrorRecord(ex, string.Format(CultureInfo.InvariantCulture, Resources.AddTabularFirstTableTerminatingError, databaseName, serverName), ErrorCategory.InvalidOperation, null));
                }
            }

        }

    }

    [Cmdlet(VerbsCommon.Add, "PartitionWithNewConnectionToTabularTable")]
    public class AddPartitionWithNewConnectionToTabularTable : TabularDatabaseBase
    {
        //  Declare mandatory parameters

        [Parameter(Mandatory = true, Position = 2)]
        [ValidateNotNullOrEmpty]
        public string datasourceConnectionString { get; set; }

        [Parameter(Mandatory = true, Position = 3)]
        [ValidateNotNullOrEmpty]
        public string connectionName { get; set; }

        [Parameter(Mandatory = true, Position = 4)]
        [ValidateNotNullOrEmpty]
        public string tableName { get; set; }

        [Parameter(Mandatory = true, Position = 5)]
        [ValidateNotNullOrEmpty]
        public string partitionName { get; set; }

        [Parameter(Mandatory = true, Position = 6)]
        [ValidateNotNullOrEmpty]
        public string selectStatement { get; set; }


        // Declare optional parameters for the Add-PartitionToTabularTable cmdlet.
        [Parameter]
        public string process { get; set; }

        // Overide the ProcessRecord method to add a Partition
        // using the supplied server name and database name 
        protected override void ProcessRecord()
        {
            //  -   process string must be a valid AMO process type or empty/null
            AMO.ProcessType? processType = null;
            if (!process.IsNullOrEmptyOrWhitespace())
            {
                processType = TabularDatabaseHelperFunctions.TryParseProcessType(process);
                if (processType == null)
                    ThrowTerminatingError(new ErrorRecord(new ArgumentException(string.Format(CultureInfo.InvariantCulture, Resources.InvalidProcessValueArgumentException, process)), string.Empty, ErrorCategory.InvalidArgument, null));
            }

            using (AMO.Server server = new AMO.Server())
            {
                try
                {
                    server.Connect(serverName);
                    using (AMO.Database database = server.Databases.GetByName(databaseName))
                    {
                        AMO2Tabular.PartitionAddWithNewConnection(database, datasourceConnectionString, connectionName, tableName, partitionName, selectStatement, true, processType);
                        WriteVerbose(string.Format(CultureInfo.InvariantCulture, Resources.AddPartitionWithNewConnectionToTabularTableWriteReport, partitionName, tableName));
                    }
                }
                catch (Exception ex)
                {
                    ThrowTerminatingError(new ErrorRecord(ex, string.Format(CultureInfo.InvariantCulture, Resources.AddTabularFirstTableTerminatingError, databaseName, serverName), ErrorCategory.InvalidOperation, null));
                }
            }

        }

    }

    [Cmdlet(VerbsCommon.Remove, "PartitionFromTabularTable")]
    public class RemovePartitionFromTabularTable : TabularDatabaseBase
    {


        [Parameter(Mandatory = true, Position = 2)]
        [ValidateNotNullOrEmpty]
        public string tableName { get; set; }

        [Parameter(Mandatory = true, Position = 3)]
        [ValidateNotNullOrEmpty]
        public string partitionName { get; set; }



        // Overide the ProcessRecord method to add a Tabular Database
        // using the supplied server name and database name 
        protected override void ProcessRecord()
        {

            using (AMO.Server server = new AMO.Server())
            {
                try
                {
                    server.Connect(serverName);
                    using (AMO.Database database = server.Databases.GetByName(databaseName))
                    {
                        AMO2Tabular.PartitionDrop(database, tableName, partitionName, true);
                        WriteVerbose(string.Format(CultureInfo.InvariantCulture, Resources.RemovePartitionFromTabularTableWriteReport, partitionName, tableName));
                    }
                }
                catch (Exception ex)
                {
                    ThrowTerminatingError(new ErrorRecord(ex, string.Format(CultureInfo.InvariantCulture, Resources.AddTabularTableTerminatingError, databaseName, serverName), ErrorCategory.InvalidOperation, null));
                }
            }

        }

    }

    [Cmdlet(VerbsCommon.Set, "NameToTabularPartition")]
    public class SetNameToTabularPartition : TabularDatabaseBase
    {
        //  Declare mandatory parameters

        [Parameter(Mandatory = true, Position = 2)]
        [ValidateNotNullOrEmpty]
        public string tableName { get; set; }

        [Parameter(Mandatory = true, Position = 3)]
        [ValidateNotNullOrEmpty]
        public string oldPartitionName { get; set; }

        [Parameter(Mandatory = true, Position = 4)]
        [ValidateNotNullOrEmpty]
        public string newPartitionName { get; set; }



        // Overide the ProcessRecord method to add a Partition
        // using the supplied server name and database name 
        protected override void ProcessRecord()
        {

            using (AMO.Server server = new AMO.Server())
            {
                try
                {
                    server.Connect(serverName);
                    using (AMO.Database database = server.Databases.GetByName(databaseName))
                    {
                        AMO2Tabular.PartitionAlterName(database, tableName, oldPartitionName, newPartitionName, true);
                        WriteVerbose(string.Format(CultureInfo.InvariantCulture, Resources.SetNameToTabularPartitionWriteReport, oldPartitionName, newPartitionName, tableName));
                    }
                }
                catch (Exception ex)
                {
                    ThrowTerminatingError(new ErrorRecord(ex, string.Format(CultureInfo.InvariantCulture, Resources.AddTabularTableTerminatingError, databaseName, serverName), ErrorCategory.InvalidOperation, null));
                }
            }

        }

    }

    [Cmdlet(VerbsCommon.Set, "SelectStatementInTabularPartition")]
    public class SetSelectStatementInTabularPartition : TabularDatabaseBase
    {
        //  Declare mandatory parameters

        [Parameter(Mandatory = true, Position = 2)]
        [ValidateNotNullOrEmpty]
        public string tableName { get; set; }

        [Parameter(Mandatory = true, Position = 3)]
        [ValidateNotNullOrEmpty]
        public string partitionName { get; set; }

        [Parameter(Mandatory = true, Position = 4)]
        [ValidateNotNullOrEmpty]
        public string selectStatement { get; set; }



        // Overide the ProcessRecord method to add a Partition
        // using the supplied server name and database name 
        protected override void ProcessRecord()
        {

            using (AMO.Server server = new AMO.Server())
            {
                try
                {
                    server.Connect(serverName);
                    using (AMO.Database database = server.Databases.GetByName(databaseName))
                    {
                        AMO2Tabular.PartitionAlterName(database, tableName, partitionName, selectStatement, true);
                        WriteVerbose(string.Format(CultureInfo.InvariantCulture, Resources.SetSelectStatementInTabularPartitionWriteReport, partitionName, tableName));
                    }
                }
                catch (Exception ex)
                {
                    ThrowTerminatingError(new ErrorRecord(ex, string.Format(CultureInfo.InvariantCulture, Resources.AddTabularTableTerminatingError, databaseName, serverName), ErrorCategory.InvalidOperation, null));
                }
            }

        }

    }

    [Cmdlet(VerbsCommon.Set, "ConnectionInTabularPartition")]
    public class SetConnectionInTabularPartition : TabularDatabaseBase
    {
        //  Declare mandatory parameters

        [Parameter(Mandatory = true, Position = 2)]
        [ValidateNotNullOrEmpty]
        public string tableName { get; set; }

        [Parameter(Mandatory = true, Position = 3)]
        [ValidateNotNullOrEmpty]
        public string partitionName { get; set; }

        [Parameter(Mandatory = true, Position = 4)]
        [ValidateNotNullOrEmpty]
        public string connectionName { get; set; }



        // Overide the ProcessRecord method to add a Partition
        // using the supplied server name and database name 
        protected override void ProcessRecord()
        {

            using (AMO.Server server = new AMO.Server())
            {
                try
                {
                    server.Connect(serverName);
                    using (AMO.Database database = server.Databases.GetByName(databaseName))
                    {
                        AMO2Tabular.PartitionAlterConnection(database, tableName, partitionName, connectionName, true);
                        WriteVerbose(string.Format(CultureInfo.InvariantCulture, Resources.SetConnectionInTabularPartitionWriteReport, partitionName, tableName));
                    }
                }
                catch (Exception ex)
                {
                    ThrowTerminatingError(new ErrorRecord(ex, string.Format(CultureInfo.InvariantCulture, Resources.AddTabularTableTerminatingError, databaseName, serverName), ErrorCategory.InvalidOperation, null));
                }
            }

        }

    }

    [Cmdlet(VerbsData.Update, "PartitionProcessInTabularTable")]
    public class UpdatePartitionProcessInTabularTable : TabularDatabaseBase
    {

        [Parameter(Mandatory = true, Position = 2)]
        [ValidateNotNullOrEmpty]
        public string tableName { get; set; }

        [Parameter(Mandatory = true, Position = 3)]
        [ValidateNotNullOrEmpty]
        public string partitionName { get; set; }

        [Parameter(Mandatory = true, Position = 4)]
        [ValidateNotNullOrEmpty]
        public string process { get; set; }


        // Overide the ProcessRecord method to add a Tabular Database
        // using the supplied server name and database name 
        protected override void ProcessRecord()
        {

            using (AMO.Server server = new AMO.Server())
            {
                //  Validate input arguments
                //  -   process string must be a valid AMO process type 
                AMO.ProcessType?  processType = TabularDatabaseHelperFunctions.TryParseProcessType(process);
                if (processType == null)
                    ThrowTerminatingError(new ErrorRecord(new ArgumentException(string.Format(CultureInfo.InvariantCulture, Resources.InvalidProcessValueArgumentException, process)), string.Empty, ErrorCategory.InvalidArgument, null));

                try
                {
                    server.Connect(serverName);
                    using (AMO.Database database = server.Databases.GetByName(databaseName))
                    {
                        AMO2Tabular.PartitionProcess(database, tableName, partitionName, processType.Value);
                        WriteVerbose(string.Format(CultureInfo.InvariantCulture, Resources.UpdatePartitionProcessInTabularTableWriteReport, partitionName, tableName));
                    }
                }
                catch (Exception ex)
                {
                    ThrowTerminatingError(new ErrorRecord(ex, string.Format(CultureInfo.InvariantCulture, Resources.AddTabularTableTerminatingError, databaseName, serverName), ErrorCategory.InvalidOperation, null));
                }
            }

        }

    }

    [Cmdlet(VerbsData.Merge, "PartitionsInTabularTable")]
    public class MergePartitionsInTabularTable : TabularDatabaseBase
    {

        [Parameter(Mandatory = true, Position = 2)]
        [ValidateNotNullOrEmpty]
        public string tableName { get; set; }

        [Parameter(Mandatory = true, Position = 3)]
        [ValidateNotNullOrEmpty]
        public string destinationPartitionName { get; set; }

        [Parameter(Mandatory = true, Position = 4)]
        [ValidateNotNullOrEmpty]
        public string[] sourcePartitionNames { get; set; }


        // Overide the ProcessRecord method to merge partitions
        // using the supplied server name and database name 
        protected override void ProcessRecord()
        {

            using (AMO.Server server = new AMO.Server())
            {

                try
                {
                    server.Connect(serverName);
                    using (AMO.Database database = server.Databases.GetByName(databaseName))
                    {
                        AMO2Tabular.PartitionAlterMerge(database, tableName, destinationPartitionName, true, sourcePartitionNames);
                        WriteVerbose(string.Format(CultureInfo.InvariantCulture, Resources.MergePartitionsInTabularTableWriteReport, sourcePartitionNames.Length, destinationPartitionName, tableName));
                    }
                }
                catch (Exception ex)
                {
                    ThrowTerminatingError(new ErrorRecord(ex, string.Format(CultureInfo.InvariantCulture, Resources.AddTabularTableTerminatingError, databaseName, serverName), ErrorCategory.InvalidOperation, null));
                }
            }

        }

    }
}
